package com.qingzhuge.web.autoconfigure;

import com.qingzhuge.autoconfigure.QingTingProperties;
import com.qingzhuge.common.utils.DataUtil;
import com.qingzhuge.web.interceptor.*;
import com.qingzhuge.web.resolver.LoginUserHandlerResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.*;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

/**
 * @author : zero.xiao
 * @description :  web mvc filter
 * @modified :
 */
@EnableWebMvc
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    protected static final Logger log = LoggerFactory.getLogger(WebConfiguration.class);
    @Autowired(required = false)
    private List<LoginUserHandlerResolver> loginUserHandlerResolvers;

    /**
     * 定义拦截器
     */
    @Autowired(required = false)
    private List<BaseInterceptor> baseInterceptors;

    @Autowired(required = false)
    private BaseAuthorizationInterceptor authorizationInterceptor;

    @Autowired
    private QingTingProperties qingTingProperties;

    @Autowired
    private LocaleInterceptor localeInterceptor;

    @Autowired
    private MaliciousRequestInterceptor maliciousRequestInterceptor;

    @Autowired(required = false)
    private EventInterceptor eventInterceptor;

    @PostConstruct
    public void started() {
        //设置时区
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        LocalDateTime date = LocalDateTime.now();
        log.debug("TimeZone start date:{}", date);
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        if (null != loginUserHandlerResolvers && loginUserHandlerResolvers.size() > 0) {
            argumentResolvers.addAll(loginUserHandlerResolvers);
        }
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if (DataUtil.isNotBlank(qingTingProperties.getRequest().getMinRequestIntervalTime())) {
            maliciousRequestInterceptor.setMinRequestIntervalTime(qingTingProperties.getRequest().getMinRequestIntervalTime());
        }
        if (null != qingTingProperties.getRequest().getMaliciousRequestWhiteUrls()) {
            maliciousRequestInterceptor.setWhiteUrls(qingTingProperties.getRequest().getMaliciousRequestWhiteUrls());
        }
        List<Interceptor> interceptorsList = new ArrayList<>();
        if (null != eventInterceptor) {
            interceptorsList.add(eventInterceptor);
        }
        if (null != baseInterceptors) {
            //添加自定义拦截器
            interceptorsList.addAll(baseInterceptors);
        }
        interceptorsList.add(maliciousRequestInterceptor);
        //把list转为数组
        Interceptor[] interceptors = new Interceptor[interceptorsList.size()];
        //把list转为数组，setNextInterceptor 参数为可变数组
        localeInterceptor.setNextInterceptor(interceptorsList.toArray(interceptors));
        registry.addInterceptor(localeInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(
                        "/*.ico",
                        "/*/api-docs",
                        "/swagger**",
                        "/swagger-resources/**",
                        "/webjars/**",
                        "/static/**",
                        "/configuration/**");
        if (null != authorizationInterceptor && qingTingProperties.getSecurity().isOpenJwt()) {
            log.debug("Turn on JWT permission validation...");
            InterceptorRegistration registration = registry.addInterceptor(authorizationInterceptor);
            //需要权限验证的url前缀
            List<String> authPath = qingTingProperties.getSecurity().getAuthUrl();
            log.debug("Permission to verify url startsWith:{}", authPath);
            if (null != authPath) {
                authPath.forEach(registration::addPathPatterns);
            }
            //需要跳过的权限验证的url前缀
            List<String> excludePath = qingTingProperties.getSecurity().getExcludeUrl();
            log.debug("Rule out verification url startsWith:{}", excludePath);
            if (null != excludePath) {
                excludePath.forEach(registration::excludePathPatterns);
            }
            registration.excludePathPatterns("/api/sms/code/**")
                    .excludePathPatterns("/api/verification/code/**")
                    .excludePathPatterns("/api/login")
                    .excludePathPatterns("/api/register");
        } else {
            log.debug("JWT permission validation is not enabled...");
        }
    }

    /**
     * 资源重定向(仅作为后台使用不提供静态资源)
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("/upload/**").addResourceLocations("./upload/");
        //如果开启了swagger api接口,则添加swagger-ui映射
        if (qingTingProperties.isSwagger()) {
            registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
            registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
            log.debug("swagger is open");
        }else{
            log.debug("swagger is close");
        }
    }
}
